-
Notifications
You must be signed in to change notification settings - Fork 14.7k
[clang][bytecode] Use Param decl as variable source if we can #152909
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This results in diagnostics that are closer to what the current interpreter produces.
@llvm/pr-subscribers-clang Author: Timm Baeder (tbaederr) ChangesThis results in diagnostics that are closer to what the current interpreter produces. Full diff: https://github.com/llvm/llvm-project/pull/152909.diff 5 Files Affected:
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index f131ac17c11bb..5275b86a57a47 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -2062,12 +2062,16 @@ bool Compiler<Emitter>::visitArrayElemInit(unsigned ElemIndex, const Expr *Init,
template <class Emitter>
bool Compiler<Emitter>::visitCallArgs(ArrayRef<const Expr *> Args,
const FunctionDecl *FuncDecl,
- bool Activate) {
+ bool Activate, bool IsOperatorCall) {
assert(VarScope->getKind() == ScopeKind::Call);
llvm::BitVector NonNullArgs;
if (FuncDecl && FuncDecl->hasAttr<NonNullAttr>())
NonNullArgs = collectNonNullArgs(FuncDecl, Args);
+ bool ExplicitMemberFn = false;
+ if (const auto *MD = dyn_cast_if_present<CXXMethodDecl>(FuncDecl))
+ ExplicitMemberFn = MD->isExplicitObjectMemberFunction();
+
unsigned ArgIndex = 0;
for (const Expr *Arg : Args) {
if (canClassify(Arg)) {
@@ -2075,8 +2079,19 @@ bool Compiler<Emitter>::visitCallArgs(ArrayRef<const Expr *> Args,
return false;
} else {
- std::optional<unsigned> LocalIndex = allocateLocal(
- Arg, Arg->getType(), /*ExtendingDecl=*/nullptr, ScopeKind::Call);
+ DeclTy Source = Arg;
+ if (FuncDecl) {
+ // Try to use the parameter declaration instead of the argument
+ // expression as a source.
+ unsigned DeclIndex = ArgIndex - IsOperatorCall + ExplicitMemberFn;
+ if (DeclIndex < FuncDecl->getNumParams())
+ Source = FuncDecl->getParamDecl(ArgIndex - IsOperatorCall +
+ ExplicitMemberFn);
+ }
+
+ std::optional<unsigned> LocalIndex =
+ allocateLocal(std::move(Source), Arg->getType(),
+ /*ExtendingDecl=*/nullptr, ScopeKind::Call);
if (!LocalIndex)
return false;
@@ -4489,14 +4504,6 @@ template <class Emitter>
unsigned Compiler<Emitter>::allocateLocalPrimitive(
DeclTy &&Src, PrimType Ty, bool IsConst, const ValueDecl *ExtendingDecl,
ScopeKind SC, bool IsConstexprUnknown) {
- // Make sure we don't accidentally register the same decl twice.
- if (const auto *VD =
- dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
- assert(!P.getGlobal(VD));
- assert(!Locals.contains(VD));
- (void)VD;
- }
-
// FIXME: There are cases where Src.is<Expr*>() is wrong, e.g.
// (int){12} in C. Consider using Expr::isTemporaryObject() instead
// or isa<MaterializeTemporaryExpr>().
@@ -4518,19 +4525,11 @@ std::optional<unsigned>
Compiler<Emitter>::allocateLocal(DeclTy &&Src, QualType Ty,
const ValueDecl *ExtendingDecl, ScopeKind SC,
bool IsConstexprUnknown) {
- // Make sure we don't accidentally register the same decl twice.
- if ([[maybe_unused]] const auto *VD =
- dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
- assert(!P.getGlobal(VD));
- assert(!Locals.contains(VD));
- }
-
const ValueDecl *Key = nullptr;
const Expr *Init = nullptr;
bool IsTemporary = false;
if (auto *VD = dyn_cast_if_present<ValueDecl>(Src.dyn_cast<const Decl *>())) {
Key = VD;
- Ty = VD->getType();
if (const auto *VarD = dyn_cast<VarDecl>(VD))
Init = VarD->getInit();
@@ -5167,7 +5166,8 @@ bool Compiler<Emitter>::VisitCallExpr(const CallExpr *E) {
return false;
}
- if (!this->visitCallArgs(Args, FuncDecl, IsAssignmentOperatorCall))
+ if (!this->visitCallArgs(Args, FuncDecl, IsAssignmentOperatorCall,
+ isa<CXXOperatorCallExpr>(E)))
return false;
// Undo the argument reversal we did earlier.
diff --git a/clang/lib/AST/ByteCode/Compiler.h b/clang/lib/AST/ByteCode/Compiler.h
index d72ffa13f6b9d..901934e530ade 100644
--- a/clang/lib/AST/ByteCode/Compiler.h
+++ b/clang/lib/AST/ByteCode/Compiler.h
@@ -306,7 +306,7 @@ class Compiler : public ConstStmtVisitor<Compiler<Emitter>, bool>,
bool visitArrayElemInit(unsigned ElemIndex, const Expr *Init,
OptPrimType InitT);
bool visitCallArgs(ArrayRef<const Expr *> Args, const FunctionDecl *FuncDecl,
- bool Activate);
+ bool Activate, bool IsOperatorCall);
/// Creates a local primitive value.
unsigned allocateLocalPrimitive(DeclTy &&Decl, PrimType Ty, bool IsConst,
diff --git a/clang/test/AST/ByteCode/cxx23.cpp b/clang/test/AST/ByteCode/cxx23.cpp
index 45dd4f528aefb..2182d7c4e4325 100644
--- a/clang/test/AST/ByteCode/cxx23.cpp
+++ b/clang/test/AST/ByteCode/cxx23.cpp
@@ -309,15 +309,14 @@ namespace NonLiteralDtorInParam {
~NonLiteral() {} // all23-note {{declared here}}
};
constexpr int F2(NonLiteral N) { // all20-error {{constexpr function's 1st parameter type 'NonLiteral' is not a literal type}} \
- // ref23-note {{non-constexpr function '~NonLiteral' cannot be used in a constant expression}}
+ // all23-note {{non-constexpr function '~NonLiteral' cannot be used in a constant expression}}
return 8;
}
void test() {
NonLiteral L;
- constexpr auto D = F2(L); // all23-error {{must be initialized by a constant expression}} \
- // expected23-note {{non-constexpr function '~NonLiteral' cannot be used in a constant expression}}
+ constexpr auto D = F2(L); // all23-error {{must be initialized by a constant expression}}
}
}
diff --git a/clang/test/AST/ByteCode/lifetimes.cpp b/clang/test/AST/ByteCode/lifetimes.cpp
index 5c8d56291f079..c8bf02c228481 100644
--- a/clang/test/AST/ByteCode/lifetimes.cpp
+++ b/clang/test/AST/ByteCode/lifetimes.cpp
@@ -94,14 +94,13 @@ namespace CallScope {
int n = 0;
constexpr int f() const { return 0; }
};
- constexpr Q *out_of_lifetime(Q q) { return &q; } // both-warning {{address of stack}}
+ constexpr Q *out_of_lifetime(Q q) { return &q; } // both-warning {{address of stack}} \
+ // expected-note 2{{declared here}}
constexpr int k3 = out_of_lifetime({})->n; // both-error {{must be initialized by a constant expression}} \
- // expected-note {{read of temporary whose lifetime has ended}} \
- // expected-note {{temporary created here}} \
+ // expected-note {{read of variable whose lifetime has ended}} \
// ref-note {{read of object outside its lifetime}}
constexpr int k4 = out_of_lifetime({})->f(); // both-error {{must be initialized by a constant expression}} \
- // expected-note {{member call on temporary whose lifetime has ended}} \
- // expected-note {{temporary created here}} \
+ // expected-note {{member call on variable whose lifetime has ended}} \
// ref-note {{member call on object outside its lifetime}}
}
diff --git a/clang/test/SemaCXX/cxx23-invalid-constexpr.cpp b/clang/test/SemaCXX/cxx23-invalid-constexpr.cpp
index 3229a91fbcefb..1c832e51c2cbc 100644
--- a/clang/test/SemaCXX/cxx23-invalid-constexpr.cpp
+++ b/clang/test/SemaCXX/cxx23-invalid-constexpr.cpp
@@ -1,4 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify=expected -std=c++23 %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected -std=c++23 %s -fexperimental-new-constant-interpreter
// This test covers modifications made by P2448R2.
|
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
clang:bytecode
Issues for the clang bytecode constexpr interpreter
clang:frontend
Language frontend issues, e.g. anything involving "Sema"
clang
Clang issues not falling into any other category
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This results in diagnostics that are closer to what the current interpreter produces.